using System;
using System.Xml;
using System.Reflection;
using System.Collections;

namespace GURUCORE.Framework.Core.Util.Configuration
{   
	public class ConfigurationBase
	{
		private ConfigurationLoader m_oLoader;
		private string m_sSection;

		public ConfigurationBase(string p_sConfigFile, string p_sSection)
		{
			m_oLoader = new ConfigurationLoader(p_sConfigFile);
			m_sSection = p_sSection;
            Load();
		}

		public ConfigurationBase(ConfigurationLoader p_oLoader, string p_sSection)
		{
			m_oLoader = p_oLoader;
			m_sSection = p_sSection;
            Load();
		}

        // HACK: Thachnn: load internally in ConfigurationBase' Constructor
		private void Load()
		{
			try
			{
				XmlDocument oXmlDoc = m_oLoader.GetSection(m_sSection);	
				XmlNodeList arrKeyNodes = oXmlDoc.FirstChild.ChildNodes;

				Type tThis = this.GetType();
				PropertyInfo[] arrProps = tThis.GetProperties();
				foreach (PropertyInfo oProp in arrProps)
				{
					object[] arrAttributes = oProp.GetCustomAttributes(typeof(ConfigurationKeyAttribute),false);
					if (arrAttributes.Length > 0)
					{
						//this is a configuration key marked property
						string sKeyName = ((ConfigurationKeyAttribute)arrAttributes[0]).KeyName;
						Type tPropType = oProp.PropertyType;
						if (tPropType == typeof(Hashtable))
						{
							Hashtable htKeys = new Hashtable();
							//find node with correct name
							foreach (XmlNode oKeyNode in arrKeyNodes)
							{
								if (oKeyNode.Name == "Key")
								{
									string sKeyNodeName = oKeyNode.Attributes["name"].Value;
									if (sKeyNodeName == sKeyName)
									{
										XmlNodeList arrSubKeyNodes = oKeyNode.ChildNodes;
										foreach (XmlNode oSubKeyNode in arrSubKeyNodes)
										{
											if (oSubKeyNode.Name == "SubKey")
											{
												string sSubKeyNodeName = oSubKeyNode.Attributes["name"].Value;
												string sSubKeyNodeValue = oSubKeyNode.Attributes["value"].Value;
												htKeys.Add(sSubKeyNodeName,sSubKeyNodeValue);
											}
										}
										oProp.SetValue(this,htKeys,null);
										break;
									}
								}
							}
						}
						else //if (tPropType == typeof(string))
						{
							//find node with correct name
							foreach (XmlNode oKeyNode in arrKeyNodes)
							{
								if (oKeyNode.Name == "Key")
								{
									string sKeyNodeName = oKeyNode.Attributes["name"].Value;
									string sKeyNodeValue = oKeyNode.Attributes["value"].Value;
									if (sKeyNodeName == sKeyName)
									{
										object oValue = Convert.ChangeType(sKeyNodeValue, tPropType);
										oProp.SetValue(this, oValue, null);
										break;
									}
								}
							}
						}
					}
				}
			}
			catch (Exception ex)
			{
				GException.ProcessException(new ConfigurationException(ex));
			}
		}
	
	}	// end class
}	// end namespace

